type Options<T> = T extends (options: infer P) => void ? P : never;

type ParametersOne<T> = T extends (result: infer P) => void ? P : never;

export const promisifyUniApi = <
  T extends (options?: Record<string, any>) => void
>(
  uniApi: T,
  options: Options<T>
) => {
  return new Promise<ParametersOne<Exclude<Options<T>, undefined>["success"]>>(
    (resolve, reject) => {
      uniApi({
        ...options,
        success(res: any) {
          resolve(res);
        },
        fail(err: any) {
          reject(err);
        },
      });
    }
  );
};

export const uniGetImageInfo = (options: UniApp.GetImageInfoOptions) =>
  promisifyUniApi<typeof uni.getImageInfo>(uni.getImageInfo, options);

export const uniSaveImageToPhotosAlbum = (
  options: UniApp.SaveImageToPhotosAlbumOptions
) =>
  promisifyUniApi<typeof uni.saveImageToPhotosAlbum>(
    uni.saveImageToPhotosAlbum,
    options
  );

export const uniShowModal = (options?: UniApp.ShowModalOptions) =>
  promisifyUniApi<typeof uni.showModal>(uni.showModal, options);
